﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using DiscoveryLogic.Common.Utilities;
using DiscoveryLogic.DataViz.NetworkDiagram.NetworkData;

namespace DiscoveryLogic.DataViz.NetworkDiagram
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class Vertice
    {
        #region props
        private Guid _ID;
        /// <summary></summary>
        public Guid ID
        {
            get
            {
                return this._ID;
            }
            set
            {
                this._ID = value;
            }
        }

        private string _Label;
        /// <summary></summary>
        public string Label
        {
            get
            {
                return this._Label;
            }
            set
            {
                this._Label = value;
            }
        }

        private float _PosX;
        /// <summary></summary>
        public float PosX
        {
            get
            {
                return this._PosX;
            }
            set
            {
                this._PosX = value;
            }
        }

        private float _PosY;
        /// <summary></summary>
        public float PosY
        {
            get
            {
                return this._PosY;
            }
            set
            {
                this._PosY = value;
            }
        }

        private float _Width;
        /// <summary></summary>
        public float Width
        {
            get
            {
                return this._Width;
            }
            set
            {
                this._Width = value;
            }
        }

        private float _Height;
        /// <summary></summary>
        public float Height
        {
            get
            {
                return this._Height;
            }
            set
            {
                this._Height = value;
            }
        }

        private string _NetworkName;
        /// <summary></summary>
        public string NetworkName
        {
            get
            {
                return this._NetworkName;
            }
            set
            {
                this._NetworkName = value;
            }
        }

        private string _PkValue;
        /// <summary></summary>
        public string PkValue
        {
            get
            {
                return this._PkValue;
            }
            set
            {
                this._PkValue = value;
            }
        }

        private string _Tooltip;
        /// <summary></summary>
        public string Tooltip
        {
            get
            {
                return this._Tooltip;
            }
            set
            {
                this._Tooltip = value;
            }
        }

        private bool _CanMove;
        /// <summary></summary>
        public bool CanMove
        {
            get
            {
                return this._CanMove;
            }
            set
            {
                this._CanMove = value;
            }
        }

        private bool _CanDrag;
        /// <summary></summary>
        public bool CanDrag
        {
            get
            {
                return this._CanDrag;
            }
            set
            {
                this._CanDrag = value;
            }
        }

        private int _VerticeColorA;
        /// <summary></summary>
        public int VerticeColorA
        {
            get
            {
                return this._VerticeColorA;
            }
            set
            {
                this._VerticeColorA = value;
            }
        }

        private int _VerticeColorR;
        /// <summary></summary>
        public int VerticeColorR
        {
            get
            {
                return this._VerticeColorR;
            }
            set
            {
                this._VerticeColorR = value;
            }
        }

        private int _VerticeColorG;
        /// <summary></summary>
        public int VerticeColorG
        {
            get
            {
                return this._VerticeColorG;
            }
            set
            {
                this._VerticeColorG = value;
            }
        }

        private int _VerticeColorB;
        /// <summary></summary>
        public int VerticeColorB
        {
            get
            {
                return this._VerticeColorB;
            }
            set
            {
                this._VerticeColorB = value;
            }
        }

        private VerticeShape _VerticeShape;
        /// <summary></summary>
        public VerticeShape VerticeShape
        {
            get
            {
                return this._VerticeShape;
            }
            set
            {
                this._VerticeShape = value;
            }
        }
        #endregion

        #region measures
        private int _Degree;
        /// <summary></summary>
        public int Degree
        {
            get
            {
                return this._Degree;
            }
            set
            {
                this._Degree = value;
            }
        }

        private int _InDegree;
        /// <summary></summary>
        public int InDegree
        {
            get
            {
                return this._InDegree;
            }
            set
            {
                this._InDegree = value;
            }
        }

        private int _OutDegree;
        /// <summary></summary>
        public int OutDegree
        {
            get
            {
                return this._OutDegree;
            }
            set
            {
                this._OutDegree = value;
            }
        }

        private double _CloseCentrality;
        /// <summary></summary>
        public double CloseCentrality
        {
            get
            {
                return this._CloseCentrality;
            }
            set
            {
                this._CloseCentrality = value;
            }
        }

        private double _BetweenCentrality;
        /// <summary></summary>
        public double BetweenCentrality
        {
            get
            {
                return this._BetweenCentrality;
            }
            set
            {
                this._BetweenCentrality = value;
            }
        }
        #endregion

        #region ctor
        /// <summary>
        /// 
        /// </summary>
        public Vertice()
        {
            this._ID = Guid.NewGuid();
            this._Label = "";
            this._PosX = 0f;
            this._PosY = 0f;
            this._Width = 0f;
            this._Height = 0f;
            this._NetworkName = string.Empty;
            this._PkValue = string.Empty;
            this._Tooltip = string.Empty;
            this._CanMove = true;
            this._CanDrag = true;
            this._VerticeColorA = 100;
            this._VerticeColorR = 0;
            this._VerticeColorG = 0;
            this._VerticeColorB = 255;
            this._VerticeShape = VerticeShape.Circle;

            this._Degree = 0;
            this._InDegree = 0;
            this._OutDegree = 0;
            this._CloseCentrality = 0;
            this._BetweenCentrality = 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="label"></param>
        /// <param name="pos"></param>
        public Vertice(Guid id, string label, PointF pos)
        {
            this._ID = id;
            this._Label = label;
            this._PosX = pos.X;
            this._PosY = pos.Y;
            this._Width = 20f;
            this._Height = 20f;
            this._NetworkName = string.Empty;
            this._PkValue = string.Empty;
            this._Tooltip = label;
            this._CanMove = true;
            this._CanDrag = true;
            this._VerticeColorA = 100;
            this._VerticeColorR = Color.DarkGreen.R;
            this._VerticeColorG = Color.DarkGreen.G;
            this._VerticeColorB = Color.DarkGreen.B;
            this._VerticeShape = VerticeShape.Circle;

            this._Degree = 0;
            this._InDegree = 0;
            this._OutDegree = 0;
            this._CloseCentrality = 0;
            this._BetweenCentrality = 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="label"></param>
        /// <param name="pos"></param>
        /// <param name="networkName"></param>
        /// <param name="pkValue"></param>
        public Vertice(Guid id, string label, PointF pos, string networkName, string pkValue)
            : this(id, label, pos)
        {
            this._NetworkName = networkName;
            this._PkValue = pkValue;
        }
        #endregion

        #region xml
        /// <summary>
        /// 
        /// </summary>
        /// <param name="xDoc"></param>
        /// <param name="vNode"></param>
        public void Save(ref XmlDocument xDoc, XmlNode vNode)
        {
            PropertyInfo[] props = this.GetType().GetProperties();
            foreach(PropertyInfo prop in props)
            {
                object propValue = prop.GetValue(this, null);
                if(propValue !=null)
                {
                    XmlDataUtil.UpdateAttribute(ref xDoc, vNode, prop.Name, propValue.ToString());
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="vNode"></param>
        /// <returns></returns>
        public Vertice Read(XmlNode vNode)
        {
            Vertice v = (Vertice) Activator.CreateInstance(this.GetType());
            PropertyInfo[] props = this.GetType().GetProperties();
            foreach (PropertyInfo prop in props)
            {
                if (vNode.Attributes.GetNamedItem(prop.Name) != null)
                {
                    string propValue = XmlDataUtil.GetAttributeValue(vNode, prop.Name, "");
                    SimpleDataType dataType = SimpleDataTypeUtil.ToSimpleDataType(prop.PropertyType);
                    object propValue2 = SimpleDataTypeUtil.ToDbValue(dataType, propValue.ToString());
                    if (propValue2 != null && propValue2 != DBNull.Value)
                        prop.SetValue(v, propValue2, null);
                }
            }

            return v;
        }
        #endregion

        public Vertice Clone()
        {
            Vertice v=new Vertice();
            PropertyInfo[] props = this.GetType().GetProperties();
            foreach (PropertyInfo prop in props)
            {
                object propValue = prop.GetValue(this, null);
                prop.SetValue(v,propValue,null);
            }
            return v;
        }
    }
}
